<template>
  <div class="trend-chart">
    <svg
      :width="width"
      :height="height"
      :viewBox="`0 0 ${width} ${height}`"
      class="chart-svg"
    >
      <!-- 背景网格线 -->
      <defs>
        <pattern
          id="grid"
          width="20"
          height="20"
          patternUnits="userSpaceOnUse"
        >
          <path
            d="M 20 0 L 0 0 0 20"
            fill="none"
            stroke="rgba(124, 58, 237, 0.1)"
            stroke-width="0.5"
          />
        </pattern>
      </defs>

      <rect width="100%" height="100%" fill="url(#grid)" />

      <!-- 价格线 -->
      <path
        :d="pathData"
        fill="none"
        :stroke="lineColor"
        stroke-width="2"
        stroke-linecap="round"
        stroke-linejoin="round"
        class="price-line"
      />

      <!-- 渐变填充区域 -->
      <defs>
        <linearGradient id="priceGradient" x1="0%" y1="0%" x2="0%" y2="100%">
          <stop offset="0%" :stop-color="lineColor" stop-opacity="0.3"/>
          <stop offset="100%" :stop-color="lineColor" stop-opacity="0"/>
        </linearGradient>
      </defs>

      <path
        :d="areaPathData"
        fill="url(#priceGradient)"
        class="price-area"
      />

      <!-- 动画点 -->
      <circle
        :cx="animatedPoint.x"
        :cy="animatedPoint.y"
        r="4"
        :fill="lineColor"
        class="animated-point"
      >
        <animate
          attributeName="r"
          values="4;6;4"
          dur="2s"
          repeatCount="indefinite"
        />
      </circle>
    </svg>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'

interface Props {
  width?: number
  height?: number
  isPositive?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  width: 200,
  height: 80,
  isPositive: true
})

const dataPoints = ref<number[]>([])
const currentIndex = ref(0)

// 生成模拟数据
const generateMockData = (): number[] => {
  const points: number[] = []
  let baseValue = 50

  for (let i = 0; i < 20; i++) {
    const randomChange = (Math.random() - 0.5) * 10
    const trend = props.isPositive ? 0.5 : -0.5
    baseValue += randomChange + trend

    // 确保值在合理范围内
    baseValue = Math.max(10, Math.min(90, baseValue))
    points.push(baseValue)
  }

  return points
}

const lineColor = computed(() =>
  props.isPositive ? '#10b981' : '#ef4444'
)

const pathData = computed(() => {
  if (dataPoints.value.length < 2) return ''

  const points = dataPoints.value.slice(0, currentIndex.value + 1)
  const stepX = props.width / (dataPoints.value.length - 1)

  let path = `M 0 ${props.height - points[0]}`

  for (let i = 1; i < points.length; i++) {
    const x = i * stepX
    const y = props.height - points[i]
    path += ` L ${x} ${y}`
  }

  return path
})

const areaPathData = computed(() => {
  if (dataPoints.value.length < 2) return ''

  const points = dataPoints.value.slice(0, currentIndex.value + 1)
  const stepX = props.width / (dataPoints.value.length - 1)

  let path = `M 0 ${props.height - points[0]}`

  for (let i = 1; i < points.length; i++) {
    const x = i * stepX
    const y = props.height - points[i]
    path += ` L ${x} ${y}`
  }

  // 闭合路径
  const lastX = (points.length - 1) * stepX
  path += ` L ${lastX} ${props.height} L 0 ${props.height} Z`

  return path
})

const animatedPoint = computed(() => {
  if (dataPoints.value.length === 0 || currentIndex.value >= dataPoints.value.length) {
    return { x: 0, y: 0 }
  }

  const stepX = props.width / (dataPoints.value.length - 1)
  const x = currentIndex.value * stepX
  const y = props.height - dataPoints.value[currentIndex.value]

  return { x, y }
})

let animationInterval: number | null = null

const startAnimation = () => {
  if (animationInterval) return

  animationInterval = setInterval(() => {
    currentIndex.value++

    if (currentIndex.value >= dataPoints.value.length) {
      // 重置动画
      currentIndex.value = 0
      dataPoints.value = generateMockData()
    }
  }, 200)
}

const stopAnimation = () => {
  if (animationInterval) {
    clearInterval(animationInterval)
    animationInterval = null
  }
}

onMounted(() => {
  dataPoints.value = generateMockData()
  startAnimation()
})

onUnmounted(() => {
  stopAnimation()
})
</script>

<style scoped lang="scss">
.trend-chart {
  .chart-svg {
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.5);
    backdrop-filter: blur(5px);
  }

  .price-line {
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
    animation: drawLine 0.2s ease-out;
  }

  .price-area {
    animation: fillArea 0.2s ease-out;
  }

  .animated-point {
    filter: drop-shadow(0 0 6px currentColor);
  }
}

@keyframes drawLine {
  from {
    stroke-dasharray: 1000;
    stroke-dashoffset: 1000;
  }
  to {
    stroke-dasharray: 1000;
    stroke-dashoffset: 0;
  }
}

@keyframes fillArea {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
</style>